package com.ruoyi.framework.web.service;


import com.ruoyi.common.constant.*;
import com.ruoyi.common.core.domain.GTPush;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.*;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import com.ruoyi.system.service.impl.SysUserServiceImpl;
import org.apache.http.util.TextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 管控相关服务类
 */
@Component
public class ControlService {

    private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class);


    @Autowired
    private ISysUserService userService;

    @Autowired
    private RedisCache redisUtil;

    @Autowired
    private IYxUserAndDeviceService yxUserAndDeviceService;

    @Autowired
    private IYxDeviceAndGetuiService yxDeviceAndGetuiService;

    @Autowired
    private IYxAvailaleTimeService yxAvailaleTimeService;

    @Autowired
    private IYxDeviceUseableTimeService yxDeviceUseableTimeService;

    @Autowired
    private IYxDeviceAppUseTimeService yxDeviceAppUseTimeService;

    @Autowired
    private IYxAndroidApplicationService yxAndroidApplicationService;


    @Autowired
    private IYxDeviceExtraInfoService yxDeviceExtraInfoService;

    @Autowired
    private IAndroidDeviceService androidDeviceService;

    public R<String> switchDeviceControlMode(Integer mode) {
        if(null == mode ){
            return R.fail("mode 不可为空");
        }
        if(mode < 0){
            return R.fail("mode 不合法");
        }
        // 获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();

        // 获取当前默认绑定设备
        YxUserAndDevice query = new YxUserAndDevice();
        query.setUserId(user.getUserId());
        query.setIsDefult(DeviceConstants.USER_DEFULT_DEVICE);
        List<YxUserAndDevice> yxUserAndDeviceList= yxUserAndDeviceService.selectYxUserAndDeviceList(query);
        if(yxUserAndDeviceList == null || yxUserAndDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }

        String deviceId = yxUserAndDeviceList.get(0).getDeviceId();

        AndroidDevice androidDevice = new AndroidDevice();
        androidDevice.setDeviceId(deviceId);
        List<AndroidDevice> androidDeviceList = androidDeviceService.selectAndroidDeviceList(androidDevice);

        if(androidDeviceList == null || androidDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }

        YxDeviceExtraInfo query2 = new YxDeviceExtraInfo();
        query2.setdId(androidDeviceList.get(0).getId());
        List<YxDeviceExtraInfo> list = yxDeviceExtraInfoService.selectYxDeviceExtraInfoList(query2);
        if(list == null || list.size() == 0){
            return R.fail("设备异常，请联系管理员");
        }

        YxDeviceExtraInfo yxDeviceExtraInfo = list.get(0);
        yxDeviceExtraInfo.setControlMode(Long.valueOf(mode));
        yxDeviceExtraInfoService.updateYxDeviceExtraInfo(yxDeviceExtraInfo);

        if(mode.equals(1)){
            sendDefultDeviceCmd(GeTuiPushConstants.DEVICE_CONTROL_MODE_OPEN);
        }else if(mode.equals(0)){
            sendDefultDeviceCmd(GeTuiPushConstants.DEVICE_CONTROL_MODE_OFF);
        }


        return R.ok("修改成功");
    }

    public R<String> captureDesktop(String taskId) {
        //获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();
        redisUtil.setCacheObject(CacheConstants.CMD_CAPTURE_KEY + taskId,user.getUserName() ,5, TimeUnit.MINUTES);


        //获取当前默认绑定设备
        YxUserAndDevice query = new YxUserAndDevice();
        query.setUserId(user.getUserId());
        query.setIsDefult(DeviceConstants.USER_DEFULT_DEVICE);
        List<YxUserAndDevice> yxUserAndDeviceList= yxUserAndDeviceService.selectYxUserAndDeviceList(query);
        if(yxUserAndDeviceList == null || yxUserAndDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }

        //通知设备 自己已绑定用户
        YxDeviceAndGetui yxDeviceAndGetui = new YxDeviceAndGetui();
        yxDeviceAndGetui.setDeviceId(yxUserAndDeviceList.get(0).getDeviceId());
        List<YxDeviceAndGetui> yxDeviceAndGetuiList = yxDeviceAndGetuiService.selectYxDeviceAndGetuiList(yxDeviceAndGetui);
        if(yxDeviceAndGetuiList != null && yxDeviceAndGetuiList.size() == 1){
            AsyncManager.me().execute(
                    AsyncFactory.transmissionPushByCid(
                            yxDeviceAndGetuiList.get(0).getCid(),
                            GTPush.create(
                                    GeTuiPushConstants.DEVICE_CAPTURE_DESKTOP,
                                    taskId,
                                    "获取桌面截图")
                    )
            );
        }

        return R.ok("发送成功");
    }

    public R<String> captureDesktopBack(String taskId,String url){
        if(TextUtils.isEmpty(taskId)){
            return R.fail("taskId 不可为空");
        }
        if(TextUtils.isEmpty(url)){
            return R.fail("url 不可为空");
        }

        String username = redisUtil.getCacheObject(CacheConstants.CMD_CAPTURE_KEY + taskId);

        Map map = new HashMap();
        map.put("taskId",taskId);
        map.put("url",url);

        //通知设备 自己已绑定用户
        YxDeviceAndGetui yxDeviceAndGetui = new YxDeviceAndGetui();
        yxDeviceAndGetui.setDeviceId(username);
        List<YxDeviceAndGetui> yxDeviceAndGetuiList = yxDeviceAndGetuiService.selectYxDeviceAndGetuiList(yxDeviceAndGetui);
        if(yxDeviceAndGetuiList != null && yxDeviceAndGetuiList.size() == 1){
            AsyncManager.me().execute(
                    AsyncFactory.transmissionPushByCid(
                            yxDeviceAndGetuiList.get(0).getCid(),
                            GTPush.create(
                                    GeTuiPushConstants.DEVICE_CAPTURE_DESKTOP,
                                    map,
                                    "获取桌面截图")
                    )
            );
        }
        return R.ok("发送成功");
    }

    public R<String> updateDeviceUseTime(YxDeviceUseTimeVo deviceUseTimeVo) {

        if(deviceUseTimeVo.getDayOfweek() == null || deviceUseTimeVo.getDayOfweek().size() == 0){
            return R.fail("数据异常，dayofweek不可为空");
        }

        if(deviceUseTimeVo.getTimeRanges() == null || deviceUseTimeVo.getTimeRanges().size() == 0){
            return R.fail("数据异常，timeRanges不可为空");
        }

        boolean isHasDay = false;
        for(YxDeviceUseTimeVo.WeekDays weekDays :deviceUseTimeVo.getDayOfweek()){
            if(weekDays.active){
                isHasDay = weekDays.active;
            }
        }
        if(!isHasDay){
            return R.fail("数据异常，weekDays.active 均为false");
        }

        // 时间数据校验
        String regex = "^([01]?[0-9]|2[0-3]):[0-5][0-9]$";
        // 编译正则表达式
        Pattern pattern = Pattern.compile(regex);

        for(YxDeviceUseTimeVo.YxAvailaleTimeVo weekDays :deviceUseTimeVo.getTimeRanges()){
            // 创建matcher对象
            if(!pattern.matcher(weekDays.startTime).matches()){
                return R.fail("数据异常，时间异常" + weekDays.startTime);
            }
            if(!pattern.matcher(weekDays.endTime).matches()){
                return R.fail("数据异常，时间异常" + weekDays.endTime);
            }
            if(getTimeDaySec(weekDays.endTime) < getTimeDaySec(weekDays.startTime)){
                return R.fail("结束时间需要大于开始时间" +weekDays.startTime + " - " + weekDays.endTime);
            }

        }

        // 获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();

        // 获取当前默认绑定设备
        YxUserAndDevice query = new YxUserAndDevice();
        query.setUserId(user.getUserId());
        query.setIsDefult(DeviceConstants.USER_DEFULT_DEVICE);
        List<YxUserAndDevice> yxUserAndDeviceList= yxUserAndDeviceService.selectYxUserAndDeviceList(query);
        if(yxUserAndDeviceList == null || yxUserAndDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }
        String deviceId = yxUserAndDeviceList.get(0).getDeviceId();

        List<YxAvailaleTime> availaleTimeList = new ArrayList<>();

        // 准备 时间段数据
        for(YxDeviceUseTimeVo.YxAvailaleTimeVo weekDays :deviceUseTimeVo.getTimeRanges()){

            YxAvailaleTime queryTime = new YxAvailaleTime();
            queryTime.setStartTime(weekDays.startTime);
            queryTime.setEndTime(weekDays.endTime);
            List<YxAvailaleTime> list = yxAvailaleTimeService.selectYxAvailaleTimeList(queryTime);

            // 存在则直接使用
            if(list != null && list.size() > 0){
                availaleTimeList.add(list.get(0));
            }else {
                // 不存在则 重新插入后 再使用
                queryTime.setCreateTime(new Date());
                yxAvailaleTimeService.insertYxAvailaleTime(queryTime);
                queryTime.setCreateTime(null);
                list = yxAvailaleTimeService.selectYxAvailaleTimeList(queryTime);
                availaleTimeList.add(list.get(0));
            }

        }

        // 开始保存 重复数据

        // 保存前先清空 之前数据
        YxDeviceUseableTime queryDt = new YxDeviceUseableTime();
        queryDt.setDeviceId(deviceId);
        List<YxDeviceUseableTime> listToDel = yxDeviceUseableTimeService.selectYxDeviceUseableTimeList(queryDt);
        if(listToDel != null && listToDel.size() > 0){
            // 使用流API提取id列表
            List<Long> ids = listToDel.stream()
                    .map(YxDeviceUseableTime::getId) // 将每个YxDeviceUseableTime对象映射到其id
                    .collect(Collectors.toList()); // 收集结果到一个新的列表
            yxDeviceUseableTimeService.deleteYxDeviceUseableTimeByIds(ids.toArray(new Long[ids.size()]));
        }

        for(YxDeviceUseTimeVo.WeekDays weekDays :deviceUseTimeVo.getDayOfweek()){
            if(weekDays.active){
                for(YxAvailaleTime availaleTime : availaleTimeList){
                    YxDeviceUseableTime yxDeviceUseableTime = new YxDeviceUseableTime();
                    yxDeviceUseableTime.setTimeId(availaleTime.getId());
                    yxDeviceUseableTime.setDeviceId(deviceId);
                    yxDeviceUseableTime.setDayOfWeek(weekDays.key);
                    yxDeviceUseableTime.setCreateTime(new Date());
                    yxDeviceUseableTimeService.insertYxDeviceUseableTime(yxDeviceUseableTime);
                }
            }
        }

        sendDefultDeviceCmd(GeTuiPushConstants.DEVICE_USE_TIME_UPDATE);

        return R.ok("保存成功");
    }

    private int getTimeDaySec(String time) {
        String[] timeS = time.split(":");
        int hour = Integer.parseInt(timeS[0]);
        int min = Integer.parseInt(timeS[1]);
        return ((hour * 60) + min) * 60;
    }

    public R<YxDeviceUseTimeVo> getDeviceUseTime(){

        // 获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();

        // 获取当前默认绑定设备
        YxUserAndDevice query = new YxUserAndDevice();
        query.setUserId(user.getUserId());
        query.setIsDefult(DeviceConstants.USER_DEFULT_DEVICE);
        List<YxUserAndDevice> yxUserAndDeviceList= yxUserAndDeviceService.selectYxUserAndDeviceList(query);
        if(yxUserAndDeviceList == null || yxUserAndDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }
        String deviceId = yxUserAndDeviceList.get(0).getDeviceId();

        // 开始查询数据
        YxDeviceUseableTime queryDt = new YxDeviceUseableTime();
        queryDt.setDeviceId(deviceId);
        List<YxDeviceUseableTime> list = yxDeviceUseableTimeService.selectYxDeviceUseableTimeList(queryDt);

        YxDeviceUseTimeVo yxDeviceUseTimeVo = new YxDeviceUseTimeVo();
        if(list != null && list.size() > 0){

            List<YxDeviceUseTimeVo.WeekDays> weekDaysList = new ArrayList<>();
            List<YxDeviceUseTimeVo.YxAvailaleTimeVo> availaleTimeVoList = new ArrayList<>();

            Set<Long> availaleTimeIds = new HashSet<>();
            Set<Integer> weekDayKey = new HashSet<>();
            for(YxDeviceUseableTime yxDeviceUseableTime : list){

                if(!weekDayKey.contains(yxDeviceUseableTime.getDayOfWeek())){
                    YxDeviceUseTimeVo.WeekDays weekDay = new YxDeviceUseTimeVo.WeekDays();
                    weekDay.active = true;
                    weekDay.setKey(yxDeviceUseableTime.getDayOfWeek());
                    weekDaysList.add(weekDay);
                    weekDayKey.add(yxDeviceUseableTime.getDayOfWeek());
                }



                if(!availaleTimeIds.contains(yxDeviceUseableTime.getTimeId())){
                    YxAvailaleTime yxAvailaleTime = yxAvailaleTimeService.selectYxAvailaleTimeById(yxDeviceUseableTime.getTimeId());
                    YxDeviceUseTimeVo.YxAvailaleTimeVo availaleTimeVo = new YxDeviceUseTimeVo.YxAvailaleTimeVo();
                    availaleTimeVo.startTime = yxAvailaleTime.getStartTime();
                    availaleTimeVo.endTime = yxAvailaleTime.getEndTime();
                    availaleTimeVoList.add(availaleTimeVo);
                    availaleTimeIds.add(yxDeviceUseableTime.getTimeId());
                }

            }

            //组装数据

            yxDeviceUseTimeVo.setDayOfweek(weekDaysList);
            yxDeviceUseTimeVo.setTimeRanges(availaleTimeVoList);
            return R.ok(yxDeviceUseTimeVo);
        }


        return R.ok(yxDeviceUseTimeVo);
    }

    public R<YxDeviceUseTimeVo> getUseTimeByDevice(){

        // 获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();

        String deviceId = user.getUserName();

        // 开始查询数据
        YxDeviceUseableTime queryDt = new YxDeviceUseableTime();
        queryDt.setDeviceId(deviceId);
        List<YxDeviceUseableTime> list = yxDeviceUseableTimeService.selectYxDeviceUseableTimeList(queryDt);

        YxDeviceUseTimeVo yxDeviceUseTimeVo = new YxDeviceUseTimeVo();
        if(list != null && list.size() > 0){

            List<YxDeviceUseTimeVo.WeekDays> weekDaysList = new ArrayList<>();
            List<YxDeviceUseTimeVo.YxAvailaleTimeVo> availaleTimeVoList = new ArrayList<>();

            Set<Long> availaleTimeIds = new HashSet<>();
            Set<Integer> weekDayIds = new HashSet<>();
            for(YxDeviceUseableTime yxDeviceUseableTime : list){

                if(!weekDayIds.contains(yxDeviceUseableTime.getDayOfWeek())){
                    YxDeviceUseTimeVo.WeekDays weekDay = new YxDeviceUseTimeVo.WeekDays();
                    weekDay.active = true;
                    weekDay.setKey(yxDeviceUseableTime.getDayOfWeek());
                    weekDaysList.add(weekDay);
                    weekDayIds.add(yxDeviceUseableTime.getDayOfWeek());
                }

                if(!availaleTimeIds.contains(yxDeviceUseableTime.getTimeId())){
                    YxAvailaleTime yxAvailaleTime = yxAvailaleTimeService.selectYxAvailaleTimeById(yxDeviceUseableTime.getTimeId());
                    YxDeviceUseTimeVo.YxAvailaleTimeVo availaleTimeVo = new YxDeviceUseTimeVo.YxAvailaleTimeVo();
                    availaleTimeVo.startTime = yxAvailaleTime.getStartTime();
                    availaleTimeVo.endTime = yxAvailaleTime.getEndTime();
                    availaleTimeVoList.add(availaleTimeVo);
                    availaleTimeIds.add(yxDeviceUseableTime.getTimeId());
                }
            }

            // 组装数据
            yxDeviceUseTimeVo.setDayOfweek(weekDaysList);
            yxDeviceUseTimeVo.setTimeRanges(availaleTimeVoList);
        }


        return R.ok(yxDeviceUseTimeVo);
    }

    public R<String> updateDeviceAppUseTime(YxDeviceUseTimeVo deviceUseTimeVo) {

        if(deviceUseTimeVo.getDayOfweek() == null || deviceUseTimeVo.getDayOfweek().size() == 0){
            return R.fail("数据异常，dayofweek不可为空");
        }

        if(deviceUseTimeVo.getTimeRanges() == null || deviceUseTimeVo.getTimeRanges().size() == 0){
            return R.fail("数据异常，timeRanges不可为空");
        }

        if(deviceUseTimeVo.daId == null || deviceUseTimeVo.daId == 0){
            return R.fail("数据异常，daId 不可为空");
        }

        boolean isHasDay = false;
        for(YxDeviceUseTimeVo.WeekDays weekDays :deviceUseTimeVo.getDayOfweek()){
            if(weekDays.active){
                isHasDay = weekDays.active;
            }
        }
        if(!isHasDay){
            return R.fail("数据异常，weekDays.active 均为false");
        }

        // 时间数据校验
        String regex = "^([01]?[0-9]|2[0-3]):[0-5][0-9]$";
        // 编译正则表达式
        Pattern pattern = Pattern.compile(regex);

        for(YxDeviceUseTimeVo.YxAvailaleTimeVo weekDays :deviceUseTimeVo.getTimeRanges()){
            // 创建matcher对象
            if(!pattern.matcher(weekDays.startTime).matches()){
                return R.fail("数据异常，时间异常" + weekDays.startTime);
            }
            if(!pattern.matcher(weekDays.endTime).matches()){
                return R.fail("数据异常，时间异常" + weekDays.endTime);
            }

            if(getTimeDaySec(weekDays.endTime) < getTimeDaySec(weekDays.startTime)){
                return R.fail("结束时间需要大于开始时间" +weekDays.startTime + " - " + weekDays.endTime);
            }

        }

        // 获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();

        // 获取当前默认绑定设备
        YxUserAndDevice query = new YxUserAndDevice();
        query.setUserId(user.getUserId());
        query.setIsDefult(DeviceConstants.USER_DEFULT_DEVICE);
        List<YxUserAndDevice> yxUserAndDeviceList= yxUserAndDeviceService.selectYxUserAndDeviceList(query);
        if(yxUserAndDeviceList == null || yxUserAndDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }

        List<YxAvailaleTime> availaleTimeList = new ArrayList<>();

        // 准备 时间段数据
        for(YxDeviceUseTimeVo.YxAvailaleTimeVo weekDays : deviceUseTimeVo.getTimeRanges()){

            YxAvailaleTime queryTime = new YxAvailaleTime();
            queryTime.setStartTime(weekDays.startTime);
            queryTime.setEndTime(weekDays.endTime);
            List<YxAvailaleTime> list = yxAvailaleTimeService.selectYxAvailaleTimeList(queryTime);

            // 存在则直接使用
            if(list != null && list.size() > 0){
                availaleTimeList.add(list.get(0));
            }else {
                // 不存在则 重新插入后 再使用
                queryTime.setCreateTime(new Date());
                yxAvailaleTimeService.insertYxAvailaleTime(queryTime);
                queryTime.setCreateTime(null);
                list = yxAvailaleTimeService.selectYxAvailaleTimeList(queryTime);
                availaleTimeList.add(list.get(0));
            }

        }

        // 开始保存 重复数据

        // 保存前先清空 之前数据
        YxDeviceAppUseTime queryDt = new YxDeviceAppUseTime();
        queryDt.setDeviceAppId(deviceUseTimeVo.daId);
        List<YxDeviceAppUseTime> listToDel = yxDeviceAppUseTimeService.selectYxDeviceAppUseTimeList(queryDt);
        if(listToDel != null && listToDel.size() > 0){
            // 使用流API提取id列表
            List<Long> ids = listToDel.stream()
                    .map(YxDeviceAppUseTime::getId) // 将每个YxDeviceUseableTime对象映射到其id
                    .collect(Collectors.toList()); // 收集结果到一个新的列表
            yxDeviceAppUseTimeService.deleteYxDeviceAppUseTimeByIds(ids.toArray(new Long[ids.size()]));
        }

        for(YxDeviceUseTimeVo.WeekDays weekDays :deviceUseTimeVo.getDayOfweek()){
            if(weekDays.active){
                for(YxAvailaleTime availaleTime : availaleTimeList){
                    YxDeviceAppUseTime yxDeviceAppUseTime = new YxDeviceAppUseTime();
                    yxDeviceAppUseTime.setTimeId(availaleTime.getId());
                    yxDeviceAppUseTime.setDeviceAppId(deviceUseTimeVo.daId);
                    yxDeviceAppUseTime.setDayOfWeek(weekDays.key);
                    yxDeviceAppUseTime.setCreateTime(new Date());
                    yxDeviceAppUseTimeService.insertYxDeviceAppUseTime(yxDeviceAppUseTime);
                }
            }
        }

        sendDefultDeviceCmd(GeTuiPushConstants.DEVICE_APP_USE_TIME_UPDATE);
        return R.ok("保存成功");
    }


    /**
     * 获取指定应用 可使用时间
     * @param daId
     * @return
     */
    public R<YxDeviceUseTimeVo> getDeviceAppUseTime(Long daId){
        // 获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();

        // 获取当前默认绑定设备
        YxUserAndDevice query = new YxUserAndDevice();
        query.setUserId(user.getUserId());
        query.setIsDefult(DeviceConstants.USER_DEFULT_DEVICE);
        List<YxUserAndDevice> yxUserAndDeviceList= yxUserAndDeviceService.selectYxUserAndDeviceList(query);
        if(yxUserAndDeviceList == null || yxUserAndDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }


        //查询历史数据

        // 保存前先清空 之前数据
        YxDeviceAppUseTime queryDt = new YxDeviceAppUseTime();
        queryDt.setDeviceAppId(daId);
        List<YxDeviceAppUseTime> list = yxDeviceAppUseTimeService.selectYxDeviceAppUseTimeList(queryDt);

        YxDeviceUseTimeVo yxDeviceUseTimeVo = new YxDeviceUseTimeVo();
        if(list != null && list.size() > 0) {

            List<YxDeviceUseTimeVo.WeekDays> weekDaysList = new ArrayList<>();
            List<YxDeviceUseTimeVo.YxAvailaleTimeVo> availaleTimeVoList = new ArrayList<>();
            Set<Long> availaleTimeIds = new HashSet<>();

            for (YxDeviceAppUseTime yxDeviceUseableTime : list) {


                YxDeviceUseTimeVo.WeekDays weekDay = new YxDeviceUseTimeVo.WeekDays();
                weekDay.active = true;
                weekDay.setKey(yxDeviceUseableTime.getDayOfWeek());
                weekDaysList.add(weekDay);

                if (!availaleTimeIds.contains(yxDeviceUseableTime.getTimeId())) {
                    YxAvailaleTime yxAvailaleTime = yxAvailaleTimeService.selectYxAvailaleTimeById(yxDeviceUseableTime.getTimeId());
                    YxDeviceUseTimeVo.YxAvailaleTimeVo availaleTimeVo = new YxDeviceUseTimeVo.YxAvailaleTimeVo();
                    availaleTimeVo.startTime = yxAvailaleTime.getStartTime();
                    availaleTimeVo.endTime = yxAvailaleTime.getEndTime();
                    availaleTimeVoList.add(availaleTimeVo);
                    availaleTimeIds.add(yxDeviceUseableTime.getTimeId());
                }

            }

            //组装数据

            yxDeviceUseTimeVo.setDayOfweek(weekDaysList);
            yxDeviceUseTimeVo.setTimeRanges(availaleTimeVoList);
            return R.ok(yxDeviceUseTimeVo);
        }
        return R.ok();
    }

    /**
     * 微信获取  应用可使用时间列表
     * @return
     */
    public R<List<YxDeviceAppUseTimeAndWeekVo>> wxGetAppUseTimeList() {

        //获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();

        //获取当前默认绑定设备
        YxUserAndDevice query = new YxUserAndDevice();
        query.setUserId(user.getUserId());
        query.setIsDefult(DeviceConstants.USER_DEFULT_DEVICE);
        List<YxUserAndDevice> yxUserAndDeviceList= yxUserAndDeviceService.selectYxUserAndDeviceList(query);
        if(yxUserAndDeviceList == null || yxUserAndDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }

        // 先查询应用列表
        List<YxAndroidApplicationVo> list = yxAndroidApplicationService.selectYxAndroidApplicationByDeviceIdAndStatus(yxUserAndDeviceList.get(0).getDeviceId(), (int) AppConstants.APP_STATUS_ENABLE);

        if(list == null || list.size() == 0){
            return R.fail("无授权应用");
        }
        // 再查询应用使用数据
        // 使用流API提取id列表
        List<Long> ids = list.stream()
                .map(YxAndroidApplicationVo::getId) // 将每个YxDeviceUseableTime对象映射到其id
                .collect(Collectors.toList()); // 收集结果到一个新的列表

        List<YxDeviceAppUseTimeVo> timelist = yxDeviceAppUseTimeService.selectYxDeviceAppUseTimeVoList(yxUserAndDeviceList.get(0).getDeviceId(), ids.toArray(new Long[ids.size()]));

        // 再重新组装数据
        List<YxDeviceAppUseTimeAndWeekVo> returnList = new ArrayList<>();
        for(YxAndroidApplicationVo yxAndroidApplicationVo : list){

            YxDeviceAppUseTimeAndWeekVo vo = new YxDeviceAppUseTimeAndWeekVo();
            vo.appId = yxAndroidApplicationVo.getId();
            vo.appName = yxAndroidApplicationVo.getAppName();
            vo.daId = yxAndroidApplicationVo.getDaId();
            vo.icon = yxAndroidApplicationVo.getIcon();
            vo.packageName = yxAndroidApplicationVo.getPackageName();


            Set<Long> availaleTimeIds = new HashSet<>();
            Set<Integer> weekKeys = new HashSet<>();
            List<YxDeviceUseTimeVo.WeekDays> weekDaysList = new ArrayList<>();
            List<YxDeviceUseTimeVo.YxAvailaleTimeVo> availaleTimeVoList = new ArrayList<>();
            String weekString = "";
            String timeRangesString = "";

            for(YxDeviceAppUseTimeVo yxDeviceAppUseTimeVo : timelist){
                if(yxAndroidApplicationVo.getId().equals(yxDeviceAppUseTimeVo.appId)){

                    if(!weekKeys.contains(yxDeviceAppUseTimeVo.dayOfWeek)){
                        YxDeviceUseTimeVo.WeekDays weekDay = new YxDeviceUseTimeVo.WeekDays();
                        weekDay.active = true;
                        weekDay.setKey(yxDeviceAppUseTimeVo.dayOfWeek);
                        weekDaysList.add(weekDay);
                        weekString += weekDay.name + " ";
                        weekKeys.add(yxDeviceAppUseTimeVo.dayOfWeek);
                    }

                    if (!availaleTimeIds.contains(yxDeviceAppUseTimeVo.avId)) {
                        YxDeviceUseTimeVo.YxAvailaleTimeVo availaleTimeVo = new YxDeviceUseTimeVo.YxAvailaleTimeVo();
                        availaleTimeVo.startTime = yxDeviceAppUseTimeVo.startTime;
                        availaleTimeVo.endTime = yxDeviceAppUseTimeVo.endTime;
                        availaleTimeVoList.add(availaleTimeVo);
                        availaleTimeIds.add(yxDeviceAppUseTimeVo.avId);
                        timeRangesString += availaleTimeVo.startTime + "-" +  availaleTimeVo.endTime + " ";
                    }

                }
            }
            //组装数据
            vo.setDayOfweek(weekDaysList);

            vo.weekString = weekString;
            vo.setTimeRanges(availaleTimeVoList);
            vo.timeRangesString = timeRangesString;

            returnList.add(vo);
        }

        return R.ok(returnList);

    }


    public R<List<YxDeviceAppUseTimeAndWeekVo>> deviceAppUseTimeList() {

        //获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();

        // 先查询应用列表
        List<YxAndroidApplicationVo> list = yxAndroidApplicationService.selectYxAndroidApplicationByDeviceIdAndStatus(user.getUserName(), (int) AppConstants.APP_STATUS_ENABLE);

        if(list == null || list.size() == 0){
            return R.fail("无授权应用");
        }
        // 再查询应用使用数据
        // 使用流API提取id列表
        List<Long> ids = list.stream()
                .map(YxAndroidApplicationVo::getId) // 将每个YxDeviceUseableTime对象映射到其id
                .collect(Collectors.toList()); // 收集结果到一个新的列表

        List<YxDeviceAppUseTimeVo> timelist = yxDeviceAppUseTimeService.selectYxDeviceAppUseTimeVoList(user.getUserName(), ids.toArray(new Long[ids.size()]));

        // 再重新组装数据
        List<YxDeviceAppUseTimeAndWeekVo> returnList = new ArrayList<>();
        for(YxAndroidApplicationVo yxAndroidApplicationVo : list){

            YxDeviceAppUseTimeAndWeekVo vo = new YxDeviceAppUseTimeAndWeekVo();
            vo.appId = yxAndroidApplicationVo.getId();
            vo.appName = yxAndroidApplicationVo.getAppName();
            vo.daId = yxAndroidApplicationVo.getDaId();
            vo.icon = yxAndroidApplicationVo.getIcon();
            vo.packageName = yxAndroidApplicationVo.getPackageName();


            Set<Long> availaleTimeIds = new HashSet<>();
            Set<Integer> weekKeys = new HashSet<>();
            List<YxDeviceUseTimeVo.WeekDays> weekDaysList = new ArrayList<>();
            List<YxDeviceUseTimeVo.YxAvailaleTimeVo> availaleTimeVoList = new ArrayList<>();
            String weekString = "";
            String timeRangesString = "";

            for(YxDeviceAppUseTimeVo yxDeviceAppUseTimeVo : timelist){
                if(yxAndroidApplicationVo.getId().equals(yxDeviceAppUseTimeVo.appId)){

                    if(!weekKeys.contains(yxDeviceAppUseTimeVo.dayOfWeek)){
                        YxDeviceUseTimeVo.WeekDays weekDay = new YxDeviceUseTimeVo.WeekDays();
                        weekDay.active = true;
                        weekDay.setKey(yxDeviceAppUseTimeVo.dayOfWeek);
                        weekDaysList.add(weekDay);
                        weekString += weekDay.name + " ";
                        weekKeys.add(yxDeviceAppUseTimeVo.dayOfWeek);
                    }

                    if (!availaleTimeIds.contains(yxDeviceAppUseTimeVo.avId)) {
                        YxDeviceUseTimeVo.YxAvailaleTimeVo availaleTimeVo = new YxDeviceUseTimeVo.YxAvailaleTimeVo();
                        availaleTimeVo.startTime = yxDeviceAppUseTimeVo.startTime;
                        availaleTimeVo.endTime = yxDeviceAppUseTimeVo.endTime;
                        availaleTimeVoList.add(availaleTimeVo);
                        availaleTimeIds.add(yxDeviceAppUseTimeVo.avId);
                        timeRangesString += availaleTimeVo.startTime + "-" +  availaleTimeVo.endTime + " ";
                    }

                }
            }
            //组装数据
            vo.setDayOfweek(weekDaysList);

            vo.weekString = weekString;
            vo.setTimeRanges(availaleTimeVoList);
            vo.timeRangesString = timeRangesString;

            returnList.add(vo);
        }

        return R.ok(returnList);

    }

    public R<String> lockScreen(String taskId) {

        //获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();

        //获取当前默认绑定设备
        YxUserAndDevice query = new YxUserAndDevice();
        query.setUserId(user.getUserId());
        query.setIsDefult(DeviceConstants.USER_DEFULT_DEVICE);
        List<YxUserAndDevice> yxUserAndDeviceList= yxUserAndDeviceService.selectYxUserAndDeviceList(query);
        if(yxUserAndDeviceList == null || yxUserAndDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }


        YxDeviceExtraInfo querye = new YxDeviceExtraInfo();
        querye.setDeviceId(yxUserAndDeviceList.get(0).getDeviceId());
        List<YxDeviceExtraInfo> list = yxDeviceExtraInfoService.selectYxDeviceExtraInfoList(querye);
        if(list == null || list.size() == 0){
            return R.fail("设备异常。请联系管理员");
        }

        YxDeviceExtraInfo yxDeviceExtraInfo = list.get(0);
        yxDeviceExtraInfo.setIsLockScreen(1l);
        yxDeviceExtraInfoService.updateYxDeviceExtraInfo(yxDeviceExtraInfo);


        return sendDefultDeviceCmdTask(taskId,GeTuiPushConstants.DEVICE_LOCK_SCREEN);
    }

    public R<String> queryTaskData(String taskId){
        String data = redisUtil.getCacheObject(CacheConstants.CMD_TASK_DATA_KEY + taskId);

        return R.ok(data);
    }

    public R<String> taskBack(String taskId,String data){
        if(TextUtils.isEmpty(taskId)){
            return R.fail("taskId 不可为空");
        }


        String username = redisUtil.getCacheObject(CacheConstants.CMD_TASK_KEY + taskId);

        // 将数据保存到 redis
        redisUtil.setCacheObject(CacheConstants.CMD_TASK_DATA_KEY + taskId,data ,5, TimeUnit.MINUTES);

        Map map = new HashMap();
        map.put("taskId",taskId);
        map.put("data",data);

        //通知设备
        YxDeviceAndGetui yxDeviceAndGetui = new YxDeviceAndGetui();
        yxDeviceAndGetui.setDeviceId(username);
        List<YxDeviceAndGetui> yxDeviceAndGetuiList = yxDeviceAndGetuiService.selectYxDeviceAndGetuiList(yxDeviceAndGetui);
        if(yxDeviceAndGetuiList != null && yxDeviceAndGetuiList.size() == 1){
            AsyncManager.me().execute(
                    AsyncFactory.transmissionPushByCid(
                            yxDeviceAndGetuiList.get(0).getCid(),
                            GTPush.create(
                                    GeTuiPushConstants.DEVICE_LOCK_SCREEN,
                                    map,
                                    "任务回执")
                    )
            );
        }
        return R.ok("发送成功");
    }

    public R<String> uploadDeviceNoticeMessgaeImmediately() {
        return sendDefultDeviceCmd(GeTuiPushConstants.DEVICE_UPLOAD_NOTICE_MESSGAE_IMMEDIATELY);
    }

    public R<String> unLockScreen(String taskId) {

        //获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();

        //获取当前默认绑定设备
        YxUserAndDevice query = new YxUserAndDevice();
        query.setUserId(user.getUserId());
        query.setIsDefult(DeviceConstants.USER_DEFULT_DEVICE);
        List<YxUserAndDevice> yxUserAndDeviceList= yxUserAndDeviceService.selectYxUserAndDeviceList(query);
        if(yxUserAndDeviceList == null || yxUserAndDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }


        YxDeviceExtraInfo querye = new YxDeviceExtraInfo();
        querye.setDeviceId(yxUserAndDeviceList.get(0).getDeviceId());
        List<YxDeviceExtraInfo> list = yxDeviceExtraInfoService.selectYxDeviceExtraInfoList(querye);
        if(list == null || list.size() == 0){
            return R.fail("设备异常。请联系管理员");
        }

        YxDeviceExtraInfo yxDeviceExtraInfo = list.get(0);
        yxDeviceExtraInfo.setIsLockScreen(0l);
        yxDeviceExtraInfoService.updateYxDeviceExtraInfo(yxDeviceExtraInfo);

        return sendDefultDeviceCmdTask(taskId,GeTuiPushConstants.DEVICE_UN_LOCK_SCREEN);
    }


    /**
     * 给自己绑定的默认设备发送 task任务
     * @param taskId 任务id
     * @param code 任务code
     * @return
     */
    public R<String> sendDefultDeviceCmdTask(String taskId,int code) {

        //获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();
        redisUtil.setCacheObject(CacheConstants.CMD_TASK_KEY + taskId,user.getUserName() ,5, TimeUnit.MINUTES);


        //获取当前默认绑定设备
        YxUserAndDevice query = new YxUserAndDevice();
        query.setUserId(user.getUserId());
        query.setIsDefult(DeviceConstants.USER_DEFULT_DEVICE);
        List<YxUserAndDevice> yxUserAndDeviceList= yxUserAndDeviceService.selectYxUserAndDeviceList(query);
        if(yxUserAndDeviceList == null || yxUserAndDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }

        //通知设备
        YxDeviceAndGetui yxDeviceAndGetui = new YxDeviceAndGetui();
        yxDeviceAndGetui.setDeviceId(yxUserAndDeviceList.get(0).getDeviceId());
        List<YxDeviceAndGetui> yxDeviceAndGetuiList = yxDeviceAndGetuiService.selectYxDeviceAndGetuiList(yxDeviceAndGetui);
        if(yxDeviceAndGetuiList != null && yxDeviceAndGetuiList.size() == 1){
            AsyncManager.me().execute(
                    AsyncFactory.transmissionPushByCid(
                            yxDeviceAndGetuiList.get(0).getCid(),
                            GTPush.create(
                                    code,
                                    taskId,
                                    "指令控制")
                    )
            );
        }
        return R.ok("发送成功");
    }

    /**
     * 给自己绑定的默认设备发送 命令
     * @param code 任务code
     * @return
     */
    public R<String> sendDefultDeviceCmd(int code) {

        //获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();


        //获取当前默认绑定设备
        YxUserAndDevice query = new YxUserAndDevice();
        query.setUserId(user.getUserId());
        query.setIsDefult(DeviceConstants.USER_DEFULT_DEVICE);
        List<YxUserAndDevice> yxUserAndDeviceList= yxUserAndDeviceService.selectYxUserAndDeviceList(query);
        if(yxUserAndDeviceList == null || yxUserAndDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }

        //通知设备
        YxDeviceAndGetui yxDeviceAndGetui = new YxDeviceAndGetui();
        yxDeviceAndGetui.setDeviceId(yxUserAndDeviceList.get(0).getDeviceId());
        List<YxDeviceAndGetui> yxDeviceAndGetuiList = yxDeviceAndGetuiService.selectYxDeviceAndGetuiList(yxDeviceAndGetui);
        if(yxDeviceAndGetuiList != null && yxDeviceAndGetuiList.size() == 1){
            AsyncManager.me().execute(
                    AsyncFactory.transmissionPushByCid(
                            yxDeviceAndGetuiList.get(0).getCid(),
                            GTPush.create(code)
                    )
            );
        }
        return R.ok("发送成功");
    }

    public R<String> captureDesktopLiveStart(String taskId) {
        return sendDefultDeviceCmdTask(taskId,GeTuiPushConstants.DEVICE_CAPTURE_DESKTOP_LIVE_START);
    }

    public R<String> captureDesktopLiveStop(String taskId) {
        return sendDefultDeviceCmdTask(taskId,GeTuiPushConstants.DEVICE_CAPTURE_DESKTOP_LIVE_STOP);
    }

    public R<String> clearAllDeviceUseTime() {

        // 获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();

        // 获取当前默认绑定设备
        YxUserAndDevice query = new YxUserAndDevice();
        query.setUserId(user.getUserId());
        query.setIsDefult(DeviceConstants.USER_DEFULT_DEVICE);
        List<YxUserAndDevice> yxUserAndDeviceList= yxUserAndDeviceService.selectYxUserAndDeviceList(query);
        if(yxUserAndDeviceList == null || yxUserAndDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }
        String deviceId = yxUserAndDeviceList.get(0).getDeviceId();

        // 保存前先清空 之前数据
        YxDeviceUseableTime queryDt = new YxDeviceUseableTime();
        queryDt.setDeviceId(deviceId);
        List<YxDeviceUseableTime> listToDel = yxDeviceUseableTimeService.selectYxDeviceUseableTimeList(queryDt);
        if(listToDel != null && listToDel.size() > 0){
            // 使用流API提取id列表
            List<Long> ids = listToDel.stream()
                    .map(YxDeviceUseableTime::getId) // 将每个YxDeviceUseableTime对象映射到其id
                    .collect(Collectors.toList()); // 收集结果到一个新的列表
            yxDeviceUseableTimeService.deleteYxDeviceUseableTimeByIds(ids.toArray(new Long[ids.size()]));
        }

        sendDefultDeviceCmd(GeTuiPushConstants.DEVICE_USE_TIME_UPDATE);

        return R.ok("清理成功");
    }

    public R<String> clearAllDeviceAppUseTime(YxDeviceUseTimeVo deviceUseTimeVo) {

        // 获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();

        // 获取当前默认绑定设备
        YxUserAndDevice query = new YxUserAndDevice();
        query.setUserId(user.getUserId());
        query.setIsDefult(DeviceConstants.USER_DEFULT_DEVICE);
        List<YxUserAndDevice> yxUserAndDeviceList= yxUserAndDeviceService.selectYxUserAndDeviceList(query);
        if(yxUserAndDeviceList == null || yxUserAndDeviceList.size() != 1){
            return R.fail("当前用户暂无绑定设备");
        }

        //  清空 之前数据
        YxDeviceAppUseTime queryDt = new YxDeviceAppUseTime();
        queryDt.setDeviceAppId(deviceUseTimeVo.daId);
        List<YxDeviceAppUseTime> listToDel = yxDeviceAppUseTimeService.selectYxDeviceAppUseTimeList(queryDt);
        if(listToDel != null && listToDel.size() > 0){
            // 使用流API提取id列表
            List<Long> ids = listToDel.stream()
                    .map(YxDeviceAppUseTime::getId) // 将每个YxDeviceUseableTime对象映射到其id
                    .collect(Collectors.toList()); // 收集结果到一个新的列表
            yxDeviceAppUseTimeService.deleteYxDeviceAppUseTimeByIds(ids.toArray(new Long[ids.size()]));
        }

        sendDefultDeviceCmd(GeTuiPushConstants.DEVICE_APP_USE_TIME_UPDATE);
        return R.ok("清除成功");
    }

    public R<Map> lockStatus() {
        //获取当前登录用户
        SysUser user = SecurityUtils.getLoginUser().getUser();

        log.debug( "bindCid  userid ：" + user.getUserId());
        SysUser indb = userService.selectUserById(user.getUserId());
        if(indb == null || indb.getAccountType() != LoginConstants.USER_TYPE_DEVICE_STU){
            return R.fail("设备信息异常");
        }

        AndroidDevice query = new AndroidDevice();
        query.setDeviceId(indb.getUserName());
        List<AndroidDevice> androidDeviceList = androidDeviceService.selectAndroidDeviceList(query);
        if(androidDeviceList == null || androidDeviceList.size() != 1){
            return R.fail("设备信息异常");
        }

        YxDeviceExtraInfo query2 = new YxDeviceExtraInfo();
        query2.setdId(androidDeviceList.get(0).getId());
        List<YxDeviceExtraInfo> list1 = yxDeviceExtraInfoService.selectYxDeviceExtraInfoList(query2);
        if(list1 == null || list1.size() == 0){
            return R.fail("设备异常，请联系管理员");
        }

        // 开始查询数据
        YxDeviceUseableTime queryDt = new YxDeviceUseableTime();
        queryDt.setDeviceId(indb.getUserName());
        List<YxDeviceUseableTime> list = yxDeviceUseableTimeService.selectYxDeviceUseableTimeList(queryDt);

        Map<String,Object> returnMap = new HashMap<>();
        returnMap.put("controlMode",list1.get(0).getControlMode());
        returnMap.put("isLockScreen",list1.get(0).getIsLockScreen());

        YxDeviceUseTimeVo yxDeviceUseTimeVo = new YxDeviceUseTimeVo();
        if(list != null && list.size() > 0){

            List<YxDeviceUseTimeVo.WeekDays> weekDaysList = new ArrayList<>();
            List<YxDeviceUseTimeVo.YxAvailaleTimeVo> availaleTimeVoList = new ArrayList<>();

            Set<Long> availaleTimeIds = new HashSet<>();
            Set<Integer> weekDayIds = new HashSet<>();
            for(YxDeviceUseableTime yxDeviceUseableTime : list){

                if(!weekDayIds.contains(yxDeviceUseableTime.getDayOfWeek())){
                    YxDeviceUseTimeVo.WeekDays weekDay = new YxDeviceUseTimeVo.WeekDays();
                    weekDay.active = true;
                    weekDay.setKey(yxDeviceUseableTime.getDayOfWeek());
                    weekDaysList.add(weekDay);
                    weekDayIds.add(yxDeviceUseableTime.getDayOfWeek());
                }

                if(!availaleTimeIds.contains(yxDeviceUseableTime.getTimeId())){
                    YxAvailaleTime yxAvailaleTime = yxAvailaleTimeService.selectYxAvailaleTimeById(yxDeviceUseableTime.getTimeId());
                    YxDeviceUseTimeVo.YxAvailaleTimeVo availaleTimeVo = new YxDeviceUseTimeVo.YxAvailaleTimeVo();
                    availaleTimeVo.startTime = yxAvailaleTime.getStartTime();
                    availaleTimeVo.endTime = yxAvailaleTime.getEndTime();
                    availaleTimeVoList.add(availaleTimeVo);
                    availaleTimeIds.add(yxDeviceUseableTime.getTimeId());
                }
            }

            // 组装数据
            yxDeviceUseTimeVo.setDayOfweek(weekDaysList);
            yxDeviceUseTimeVo.setTimeRanges(availaleTimeVoList);
            returnMap.put("deviceUseAbleTime",yxDeviceUseTimeVo);
        }else {
            returnMap.put("deviceUseAbleTime",null);
        }


        return R.ok(returnMap);
    }


}
